﻿using System.Diagnostics;
using System.Linq;
using System.Windows.Controls;
using System.Windows;
using System;
using System.Windows.Input;
using Redbrick.Silverlight.UI;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Moria.Common.Model;
using Moria.Common;
namespace Moria.Silverlight
{


    public class MoriaPage : Page
    {
        #region Consts & Settings


        #endregion Consts & Settings

        #region Declarations

        public static readonly DependencyProperty KeysSourceProperty = DependencyProperty.RegisterAttached("Keys", typeof(ObservableCollection<KeyCommand>), typeof(MoriaPage), null);
        private static Dictionary<UIElement, bool> kbAttached = new Dictionary<UIElement, bool>();

        #endregion Declarations

        #region Constructor

        public MoriaPage()
        {
            this.KeyBindings = new ObservableCollection<KeyCommand>();
        }

        #endregion Constructor

        #region Methods

        private void ProcessKeyEvent(IEnumerable<KeyCommand> commands, KeyEventArgs e)
        {
            if (commands == null || commands.Count() == 0) return;
            foreach (KeyCommand cmd in commands)
            {
                if (cmd.Key != e.Key) continue;
                ICommand command = Moria.GetCommand(cmd.Command);
                if (command != null && command.CanExecute(e.OriginalSource))
                {
                    command.Execute(e.OriginalSource);
                    e.Handled = true;
                }
            }
        }
        protected bool AttachKeyboardHandler(UIElement el)
        {
            try
            {
                if (!kbAttached.ContainsKey(el))
                {
                    kbAttached[el] = true;

                    el.AddHandler(UIElement.KeyDownEvent, new KeyEventHandler(this.KeyDown_Handler), true);
                    el.AddHandler(UIElement.KeyUpEvent, new KeyEventHandler(this.KeyUp_Handler), true);
                }

                return true;
            }
            catch (Exception err)
            {
                Debug.WriteLine("Exception:" + err);
            }
            return false;
        }

        #endregion Methods

        #region Events

        private void KeyUp_Handler(object sender, KeyEventArgs e)
        {
            ProcessKeyEvent(this.KeyBindings.Where(c => c.EventType == KeyEventType.KeyUp), e);

        }
        private void KeyDown_Handler(object sender, KeyEventArgs e)
        {
            ProcessKeyEvent(this.KeyBindings.Where(c => c.EventType == KeyEventType.KeyDown), e);

        }
    
        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {
            Debug.WriteLine("My Uri:" + e.Uri);

            this.AttachKeyboardHandler(this);

            UIElement el = e.Content as UIElement;
            if (el != null)
            {
                this.AttachKeyboardHandler(el);

                foreach (var child in el.GetVisualsOfType<UIElement>())
                {
                    this.AttachKeyboardHandler(child);
                }
            }

            base.OnNavigatedTo(e);
        }

        #endregion Events

        #region Properties

        protected TheGame Moria { get { return this.DataContext == null ? null : this.DataContext as TheGame; } }
        public ObservableCollection<KeyCommand> KeyBindings
        {
            get { return this.GetValue(KeysSourceProperty) as ObservableCollection<KeyCommand>; }
            set { this.SetValue(KeysSourceProperty, value); }
        }

        #endregion Properties
    }

}
